package com.thero.core.chess;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by wusk on 2017/11/27.
 */
public class Chessboard {
    public static final int POINT_COUNT = 24;

    private Map<Integer, Point> points;

    public Chessboard(){
        points = new HashMap<>(POINT_COUNT);

        Point p11 = new Point(11, 0, 41, 71, 0, 14, 17);
        Point p41 = new Point(41, 11, 0, 71, 0, 42, 43);
        Point p71 = new Point(71, 11, 41, 0, 0, 74, 77);

        this.points.put(p11.key(), p11);
        this.points.put(p41.key(), p41);
        this.points.put(p71.key(), p71);

        //第二行
        Point p22 = new Point(22, 0, 42, 62, 0, 24, 26);
        Point p42 = new Point(42, 22, 0, 62, 41, 0, 43);
        Point p62 = new Point(62, 22, 42, 0, 0, 64, 66);

        this.points.put(p22.key(), p22);
        this.points.put(p42.key(), p42);
        this.points.put(p62.key(), p62);

        //第三行
        Point p33 = new Point(33, 0, 43, 53, 0, 34, 35);
        Point p43 = new Point(43, 33, 0, 53, 41, 42, 0);
        Point p53 = new Point(53, 33, 43, 0, 0, 54, 55);

        this.points.put(p33.key(), p33);
        this.points.put(p43.key(), p43);
        this.points.put(p53.key(), p53);

        //第四行左
        Point p14 = new Point(14, 0, 24, 34, 11, 0, 17);
        Point p24 = new Point(24, 14, 0, 34, 22, 0, 26);
        Point p34 = new Point(34, 14, 24, 0, 33, 0, 35);

        this.points.put(p14.key(), p14);
        this.points.put(p24.key(), p24);
        this.points.put(p34.key(), p34);

        //第四行右
        Point p54 = new Point(54, 0, 64, 74, 53, 0, 55);
        Point p64 = new Point(64, 54, 0, 74, 62, 0, 66);
        Point p74 = new Point(74, 54, 64, 0, 71, 0, 77);

        this.points.put(p54.key(), p54);
        this.points.put(p64.key(), p64);
        this.points.put(p74.key(), p74);

        //第五行
        Point p35 = new Point(35, 0, 45, 55, 33, 34, 0);
        Point p45 = new Point(45, 35, 0, 55, 0, 46, 47);
        Point p55 = new Point(55, 35, 45, 0, 53, 54, 0);

        this.points.put(p35.key(), p35);
        this.points.put(p45.key(), p45);
        this.points.put(p55.key(), p55);

        //第六行
        Point p26 = new Point(26, 0, 46, 66, 22, 24, 0);
        Point p46 = new Point(46, 26, 0, 66, 45, 0, 47);
        Point p66 = new Point(66, 26, 46, 0, 62, 64, 0);

        this.points.put(p26.key(), p26);
        this.points.put(p46.key(), p46);
        this.points.put(p66.key(), p66);

        //第七行
        Point p17 = new Point(17, 0, 47, 77, 11, 14, 0);
        Point p47 = new Point(47, 17, 0, 77, 45, 46, 0);
        Point p77 = new Point(77, 17, 47, 0, 71, 74, 0);

        this.points.put(p17.key(), p17);
        this.points.put(p47.key(), p47);
        this.points.put(p77.key(), p77);
    }

    public int checkThree(int location, Player player){
        Point point = points.get(location);
        return checkThree(point, player.selfColor());
    }

    public int checkThree(Point point, Color color){
        Piece piece = point.getPiece();
        if(null == piece){
            return 0;
        }
        if(!color.equals(piece.getColor())){
            return 0;
        }
        int count = 0;
        if( checkLine(point.horizontal(), color)){
            count = count + 1;
        }
        if(checkLine(point.vertical(), color)){
            count = count + 1;
        }
        return count;
    }

    private boolean checkLine(int[] index, Color color){
        for(int i: index){
            if(i > 0){
                Point point = this.points.get(i);
                Piece piece = point.getPiece();
                if(null == piece){
                    return false;
                }
                if(!color.equals(piece.getColor())){
                    return false;
                }
            }
        }
        return true;
    }

    public short put(int location, Player player){
        Point point = points.get(location);
        if(null != point.getPiece()){
            return 3501;
        }
        if(!point.isValid()){
            return 3502;
        }
        Piece piece = player.takePiece();
        if(null == piece){
            return 3503;
        }
        point.setPiece(piece);
        return 0;
    }

    public boolean canKill(Player player){
        Color color = player.rivalColor();
        Set<Integer> set = points.keySet();
        for(int key: set){
            Point point = points.get(key);
            Piece piece = point.getPiece();
            if(null != piece && color.equals(piece.getColor())){
                int count = checkThree(point, color);
                if(0 == count){
                    return true;
                }
            }
        }
        return false;
    }

    public short kill(int location, Stage stage, Player player){
        Point point = points.get(location);
        Piece piece = point.getPiece();
        //无子
        if(null == piece){
            return 5501;
        }
        //己方棋子
        if(piece.getColor().equals(player.selfColor())){
            return 5502;
        }
        //对方成三棋子
        if(checkThree(point, player.rivalColor()) > 0){
            return 5503;
        }
        point.removePiece();
        if(Stage.put.equals(stage)){
            point.invalid();
        }
        return 0;
    }

    public short move(int source, int target, Player player){
        Point spoint = points.get(source);
        if(spoint.isEmpty()){
            return 4501;
        }
        if(!player.selfColor().equals(spoint.getPiece().getColor())){
            return 4502;
        }
        Point tpoint = points.get(target);
        if(tpoint.isFilled()){
            return 4503;
        }
        if(!spoint.isAdjacent(target)){
            return 4504;
        }
        Piece piece = spoint.pickup();
        tpoint.setPiece(piece);
        return 0;
    }

    public boolean pickup(int location, Player player){
        Point point = points.get(location);
        Piece piece = point.getPiece();
        if(null == piece){
            return false;
        }
        if(!player.selfColor().equals(piece.getColor())){
            return false;
        }
        if(piece.isPick()){
            return true;
        }
        piece.pickup();
        return true;
    }

    public boolean unpick(int location, Player player){
        Point point = points.get(location);
        Piece piece = point.getPiece();
        if(null == piece){
            return false;
        }
        if(!player.selfColor().equals(piece.getColor())){
            return false;
        }
        if(!piece.isPick()){
            return true;
        }
        piece.unpick();
        return true;
    }

    public int pieceCount(Player player){
        int count = 0;
        Set<Integer> set = points.keySet();
        for(int key: set){
            Point point = points.get(key);
            Piece piece = point.getPiece();
            if(null != piece && player.selfColor().equals(piece.getColor())){
                count = count + 1;
            }
        }
        return count;
    }

    public void allValid(){
        Set<Integer> set = points.keySet();
        for(int key: set){
            Point point = points.get(key);
            if(!point.isValid()){
                point.valid();
            }
        }
    }
}
